#ifndef SPREADSHEET_H
#define SPREADSHEET_H

/*****************************************************************************************
  @copyright  2020-2021
  @date       2021-03-09
  @author     qiaowei
  @contact    weiweiqiao@126.com
  @version    1.0
  @brief      xls窗体
  @history    NONE
******************************************************************************************/

#include <QTableWidget>

class Cell;
class QAction;
class QProgressDialog;

class SpreadSheet : public QTableWidget
{
    Q_OBJECT
public:
    explicit SpreadSheet(QWidget *parent = 0);

    /***************************************************************************
     @date     2021-03-09
     @author   qiaowei
     @contact  weiweiqiao@126.com
     @version  1.0
     @brief    创建新xls窗体并返回
     @param    widget 父窗体
     @return   创建的新xls
    ***************************************************************************/
    static SpreadSheet* newFile(QWidget* widget);

    static SpreadSheet* open(QWidget* parent);

    /**
      descr:return the mAutoRecalculated value.
      return:mAutoRecalculated value.
    */
    bool autoRecalculate() const;

    /**
      descr:set the mAutoRecalculated value by recalculateFlag;
    */
    void setAutoRecalculate(bool recalculateFlag);

    /**
      descr:return the active cell's coordinate.
      return:cell's coordinate in string format.
    */
    QString currentLocation() const;

    /**
      descr:return the active cell's formula.
      return:cell's formula in string format.
    */
    QString currentFormula() const;

    /**
      descr:get spreadsheet's widget action.
      return:widget in QAction.
    */
    QAction* windowMenuAction() const;

    /**
      descr:return the selected range by user.
      return:selected range.
    */
    QTableWidgetSelectionRange selectedRange() const;

    /**
      descr:initialize the spread content.
    */
    void clear();

    /**
      descr:set all of the cells to be dirty and call update method.
    */
    void recalculate();

    /**
      descr:cut the selected items.
    */
    void cut();

    /**
      descr:delete the selected items.
    */
    void del();

    void copy(); 

    void save();

    bool saveAs();

private:
    static void setFileAttribute(SpreadSheet* sheet, const QString& filePath);

    SpreadSheet* openFile(SpreadSheet* sheet, const QString filePath);
    /**
      descr:return the cell's text in coordiante(row, column).
      param:(row, column) coordiante.
      return:text's contents.
    */
    QString text(int row, int column) const;

    /**
      descr:get cell data in coordinate(row, column).
      param:row x coordinate;column y coordinate.
      return:the fomula of cell in coordinate(row, column).
    */
    QString formula(int row, int column) const;

    /**
      descr:set the formula of cell in coordinate(row, column) with string.
      param:
    */
    void setFormula(int row, int column, const QString& str);

    /**
      descr:return the cell in coordinate(row, column).
      param:row x coordiante; column y coordinate.
      return: the cell in coordinate(row, column), if no cell, return 0.
    */
    Cell* cell(int row, int column) const;

    /**
      descr:set the selected row is the current row.
    */
    void selectCurrentRow();

    /**
      descr:set the selected column is the current column.
    */
    void selectCurrentColumn();

    /**
      descr:flag each cell to dirty state to recalculate.
    */
    void somethingChanged();

    /**
      descr:set pActionActive's value and create SIGNAL/SLOT.
    */
    void setActionActive();

    /**
      @brief read content from choosed file.
      @param filePath filename and filepath.
      @return true read file successfully.
    */
    bool readFile(const QString& filePath);

    /**
      @brief write content from spreadsheet to file.
      @param filePath filename and filepath.
      @return true write file successfully.
    */
    bool writeFile(const QString& filePath);

    /**
      descr:return file name without file path.
      param:filePath file name with file path.
      return:file name.
    */
    QString strippedName(const QString& filePath);

    QProgressDialog* progressDialog(QWidget* widget, const QString& str, const int range);

signals:
    void modified();

private:
    //max row and column count in spread.
    static const int mMaxRow;
    static const int mMaxColumn;

    static int doc_number_;

    //magicnumber.
    enum {MagicNumber = 0x7F51C883};

    QAction* pActionActive;

    QString mCurFile;

    bool mIsSaved;

    bool mAutoRecalculated;

};

#endif // SPREADSHEET_H
